/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package czStvDpds.centrallogic;

import czStvDpds.bullets.AbstractBullet;
import czStvDpds.bullets.Bullet;
import czStvDpds.graphics3D.*;
import czStvDpds.graphics3D.gui.LButton;
import czStvDpds.graphics3D.gui.LCardContainer;
import czStvDpds.graphics3D.gui.LCheckbox;
import czStvDpds.graphics3D.gui.LGridPanel;
import czStvDpds.graphics3D.gui.LTextField;
import czStvDpds.graphics3D.gui.SuperContainer;
import czStvDpds.movement.AbstractPlayer;
import czStvDpds.movement.Player;
import czStvDpds.network.PacketMaker;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import menu.PausedGameMenu;
import menu.TitleMenu;
import org.lwjgl.opengl.Display;

/**
 *
 * @author Vašek
 */
public class Logic implements GraphicsEndProcessor {

    final static int maxPlayers = 16;
    Drawing d;
    AbstractPlayer[] players;
    ArrayList<AbstractBullet> bullets; //ArrayList - bude potřeba častěji odebírat nebo přidávat
    final static double sqrt2 = 1.414214;
    final static double mouseSensitivity = 0.4;
    final static int refreshTime = 40;
    final static int shotDelay = 500; //Čas mezi střelami v ms
    boolean forward, back, left, right;
    //Část o vyrovnávání pohybu
    long lastRefresh;
    long newTime;
    int diff = refreshTime; //difference (rozdíl)
    Timer timer;
    PacketMaker maker;
    long shotTime = 0;

    public Logic() {
        this.d = GraphicsIndex.getDrawing();
        this.players = new AbstractPlayer[maxPlayers];
        bullets = new ArrayList<>();
        Player p = new Player(7, 15, 0, "TestingPlayer");
        addPlayer(p, 0);
        addBullet(new Bullet(7, 6, 22.5, 0.001, 0));
        d.locateCameraToPlayer(p, 0.4f);
        d.freeCamera(false);
        d.addGraphicsEndProcessor(this);
        lastRefresh = new Date().getTime();
        timer = new Timer();
        timer.scheduleAtFixedRate(new UpdateTimer(), 100, refreshTime); //Delay, period
//        this.createBasicGui();
        this.createGui();
    }

    @Override
    public void graphicsEnded() {
        timer.cancel();
    }

    public void addGraphicsEndProcessor(GraphicsEndProcessor gep) {
        d.addGraphicsEndProcessor(gep);
    }
    //<editor-fold defaultstate="collapsed" desc="jednoduché metody">

    public void setPacketMaker(PacketMaker maker) {
        this.maker = maker;
        if (maker != null) {
            maker.zpracujZero(players[0].getName());
        }
    }

    public void addPlayer(Player p, int id) {
        d.addPlayer(p);
        players[id] = p;
        if (maker != null) {
            maker.zpracujZero(p.getName());
        }
    }

    public void removePlayer(int id) {
        d.removePlayer((GraphicalPlayer) players[id]);
        players[id] = null;
    }

    public void toggleCursor() {
        d.setCursorHidden(!d.isCursorHidden());
    }

    public void toggleLIA() {
//        d.toggleLIA();
        d.freeCamera(!d.isCameraFree());
        GraphicsIndex.getInputHandler().setRepeatEvents(d.isCameraFree());
    }

    public boolean isCameraFree() {
        return d.isCameraFree();
    }

    public void moveCamera(double by) {
        d.moveCamera((float) by);
    }

    public void rotateCamera(double x, double y) {
        d.rotateCamera((float) (-x * mouseSensitivity), (float) (y * mouseSensitivity));
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="manipulace s hráčem">
    public void movePlayer(PlayerMovement m) {

        if (m != null) {
            players[m.getPlayer()].movePlayer(m, diff);
        }
    }

    public void movePlayer(PlayerMovement m, int time) {
        if (m != null) {
            players[m.getPlayer()].movePlayer(m, time);
        }
    }

    public void movePlayer(PlayerMovement m, boolean shorten) {
        if (m != null) {
            if (shorten) {
                players[m.getPlayer()].movePlayer(m, (int) (diff / sqrt2));
            } else {
                players[m.getPlayer()].movePlayer(m, diff);
            }
        }
    }

    public AbstractPlayer getPlayer(int i) {
        return players[i];
    }

    public AbstractPlayer[] getPlayerArray() {
        return players;
    }

    public void toggleDirection(Direction d, boolean to) {
        switch (d) {
            case FORWARD:
                forward = to;
                break;
            case BACK:
                back = to;
                break;
            case LEFT:
                left = to;
                break;
            case RIGHT:
                right = to;
                break;
        }
    }
    //</editor-fold>

    public void shoot() {
        long time = new Date().getTime();
        if (time > shotTime) { //může střelit
            shotTime = time + shotDelay;
            addBullet(new Bullet(players[0].getX(), players[0].getY(), players[0].getYaw(), 0.001, 0));
        }
    }

    public void addBullet(Bullet b) {
        bullets.add(b);
        d.addBulet(b);
    }

    public AbstractBullet getBullet(int i) {
        return bullets.get(i);
    }

    public void removeBullet(int i) {
        d.removeBullet((GraphicalBullet) bullets.remove(i));

    }

    public void removeBullet(AbstractBullet b) {
        d.removeBullet((GraphicalBullet) b);
        bullets.remove(b);
    }
    ///////////////////////////návrh práce s gui////////////////////////////
    private LCardContainer gameMenu;
    private LGridPanel panel, panel2;

    
    @Deprecated
    private void createBasicGui() {
        //tvorba komponent
        this.gameMenu = SuperContainer.create(SuperContainer.GAME_MENU, d.getGUIScene(SuperContainer.GAME_MENU));
        LCheckbox checkbox1 = new LCheckbox("C-box");
        LButton button1 = new LButton("Button");
        LTextField textField1 = new LTextField("123456789");
//        LLabel label2 = new LLabel("Label 2");
//        LLabel label3 = new LLabel("Label 3");
//        LLabel[] labels = new LLabel[2];
        panel = new LGridPanel(3, 1);

        //pridavani, poradi od nejvetsiho komponentu k nejmensimu treba vzdy dodrzet
        this.gameMenu.addComponent(panel, 0);
        panel.addComponent(textField1);
        panel.addComponent(checkbox1);
        panel.addComponent(button1);
//        for (int i = 0; i < labels.length; i++) {
//            labels[i] = new LLabel("Label " + (i + 2));
//            panel2.addComponent(labels[i]);
//        }
    }
    
    private void createGui(){
        TitleMenu.init(this);
        PausedGameMenu.init(this);
    }

    public void toggleGUIGameMenu() {

        SuperContainer.switchContainer(SuperContainer.GAME_MENU);
        d.setGUISceneVisibility(SuperContainer.GAME_MENU, !d.getGUISceneVisibility(SuperContainer.GAME_MENU));

        SuperContainer.getAsContainer(SuperContainer.GAME_MENU).showComponent(panel);
    }
    
    public void networkConnect(String host){
        
    }
    
    public void exitGame(){
        
    }
    
    public void changeLocalPlayerName(String newName){
        
    }

    private class UpdateTimer extends TimerTask {

        @Override
        public void run() {
            boolean shorten = false;
            //Tato část slouží k vyrovnávání pohybu když se třeba hra sekne
            //a refreshuje se třeba až za 500 ms
            newTime = new Date().getTime();
            diff = (int) (newTime - lastRefresh);
            lastRefresh = newTime;
            if ((forward || back) && (left || right)) { //Když to jsou 2 směry
                shorten = true;
            }
            double x = players[0].getX();
            double y = players[0].getY();
            double yaw = players[0].getYaw();
            if (forward) {
                movePlayer(new PlayerMovement(0, Direction.FORWARD), shorten);
            }
            if (back) {
                movePlayer(new PlayerMovement(0, Direction.BACK), shorten);
            }
            if (left) {
                movePlayer(new PlayerMovement(0, Direction.LEFT), shorten);
            }
            if (right) {
                movePlayer(new PlayerMovement(0, Direction.RIGHT), shorten);
            }
            if (players[0].getX() != x || players[0].getY() != y
                    || players[0].getYaw() != yaw) {//Pokud se jeho pozice změnila
                maker.zpracujFirst(x, y, yaw);
            }

            for (int i = 0; i < bullets.size(); i++) {
                bullets.get(i).step(diff);
            }
        }
    }
}
